#ifndef MRE_AGENT_ALI
#define MRE_AGENT_ALI

#include "Util.h"
#include "TFGenerator.h"
#include "RFGeneralizer.h"
#include "types.h"

#ifdef USE_THREADS
#include <boost/thread/thread.hpp>
#endif 

class Statistics
{
public:
	Statistics(){ age = trialAge = episodeAge = trialEpisode=  0 ; overalReward = trialReward = episodeReward = 0; hasSeenShortEpisode= 0;trial =0;}
	void saveToFile(FILE* fout)
	{
		fprintf(fout,"%d %ld %lf\n", trial, age, overalReward); 
	}
	void loadFromFile(FILE* fin)
	{
		trialAge = episodeAge = 0; 
		trialReward = 0; 
		fscanf(fin,"%d %ld %lf\n",&trial,  &age, &overalReward); 
	}
	long age;					//total number of steps 
	int trial;					//which trial are we in
	long startingTime;			//time when app. started
	long trialAge;				//total number of steps in current trial
	int episodeAge;				//number of steps in the current episode
	int trialEpisode;			//number of episodes in this trial
	double overalReward;	//cumulative reward so far
	double trialReward;		//cumulative reward in the current trial
	double episodeReward;	//cumulative reward in the current episode
	int hasSeenShortEpisode;  //have we seen a good episode? (episode ended with in a goal state)
};
class MDPSolver; 
class MREAgent
{
public:
	MREAgent(void);
	~MREAgent(void);
	void init(const char* ts);
	Action start(Observation o);
	Action step(Reward r, Observation o);
	void end(Reward r);
	void cleanup();
	char* getName();
	const char* message(const char* msg); 
	void loadHistory(const char* fname);
/*
void saveHistory(const char* fname);
*/
	void loadParam(const char* fname); 
	
	Action mapAction(Action a);
	void bringObservation2bound(Observation o); 
	void initGeneralizers(); 
	void learnGeneralization( Transition* t); 

// Observation related methods
static void printObservation(Observation o); 
char* sprintObservation(Observation o); 
static void copyObservation(const Observation o, Observation&); 
static Observation copyObservation(const Observation o); 

	Action randomAction();
	void addToHistory(Transition& t); 
	void clearHistory(); 
	void solveModel(Observation currentState); 
	Action getBestAction(Observation state); 

//void loadHistory(const char* fname); 

public:
	taskspec_t taskSpec;
	Action lastAction;			//the action that was taken last step
	Observation lastState; 

    char* name; 
	static ENVIRONMENT environment; 
	Statistics stats;

	list<Transition> history; 

	TFGenerator * tfGens; 
	RFGeneralizer* rfGens; 

	MDPSolver* mdpSolver; 

#ifdef USE_THREADS
	boost::thread* plannerThread; 
#endif

	int mappedAction [25]; 
	int numberOfActions; 
	static int dimension; 
};

#endif
